#include "fxcc/core/graph/opengl3/ImGuiGlfwApp.h"
#include "fxcc/imgui/Editor.h"

using namespace fxcc::platform;
using namespace fxcc::graph;
using namespace fxcc::graph::opengl3;
using namespace fxcc::imgui::graph::opengl3;
using BaseApp = fxcc::imgui::graph::opengl3::GlfwApp;

#undef main


struct SimpleApp : public BaseApp
{
public:

    std::shared_ptr<fxcc::graph::opengl3::Effect3d> m_Effect;
    
    fxcc::graph::common::Camera camera;
    fxcc::graph::common::Transform transform;

    std::shared_ptr<fxcc::graph::opengl3::MeshJack> m_CubeMesh;
    std::shared_ptr<fxcc::graph::opengl3::RenderTargetJack> m_RenderTargetJack;

    glm::vec4 color;
    SimpleApp(const fxcc::platform::common::App::Desc& desc) : BaseApp(desc), color(1.0)
    {
    }
    bool Init() override
    {
        if (!BaseApp::Init())
        {
            return false;
        }

        if (!LoadScript())
        {
            return false;
        };

        if (!InitResources())
        {
            return false;
        }


        return true;
    };


    bool LoadScript()
    {

        return true;
    }

    void printOpenGLESVersion()
    {
        const char *version = (const char *)glGetString(GL_VERSION);
        std::cout << "OpenGL ES Version: " << version << std::endl;
    };

    bool InitResources()
    {
        auto& io = ImGui::GetIO();
        ImFont* font = io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\verdanab.ttf", 32.0f);  

        m_Effect = std::make_shared<fxcc::graph::opengl3::Effect3d>(R"(

out vec4 FragColor;

void main()
{
    FragColor=vec4(1.0f,0.5f,0.5,1.0f);
};
)", true);

        m_CubeMesh = std::make_shared<fxcc::graph::opengl3::MeshJack>(fxcc::graph::common::Geometry::CreateBox());

        camera.SetPosition(glm::vec3(5.0f));
        camera.LookAt(glm::vec3(0.0f));

        return true;
    };

    fxcc::imgui::Editor editor;

    void OnClose() override
    {
        BaseApp::OnClose();
    }
    void OnEdit() override
    {
        ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());
        ImGui::Begin("Dll Export");
        editor.AddFrameBuffer(m_RenderTargetJack->GetTexture(0));
        ImGui::End();

    }
    void OnDestroy() override
    {
        ztclog::info("mono destroy");
        BaseApp::OnDestroy();
    }
    void OnFrameRender() override
    {
        glViewport(0, 0, m_Desc.m_Size.x, m_Desc.m_Size.y);

        m_RenderTargetJack->Begin();

        glClearColor(color.x, color.y, color.z, color.w);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        m_Effect->Begin();
        m_Effect->SetCamera(camera);
        m_Effect->SetObjData(transform);

        m_Effect->SetFixed();
        m_CubeMesh->Bind();
        m_CubeMesh->DrawElementsAuto();

        m_Effect->End();

        m_RenderTargetJack->End();
    };

    void OnFramebuffersize(int w, int h) override
    {
        opengl3::GlfwApp::OnFramebuffersize(w, h);
        camera.SetAspect(m_Desc.Aspect());

        fxcc::graph::common::RenderTargetJack::Desc desc(1, { w, h ,4,0 });
        m_RenderTargetJack = std::make_shared<fxcc::graph::opengl3::RenderTargetJack>(desc);
    }
    void OnUpdate() override
    {
        opengl3::GlfwApp::OnUpdate();

        float ctTime = m_GlfwlTimer.m_CurrentTime;
        float deltaTime = m_GlfwlTimer.m_DeltaTime;
    }
};

int main()
{
    ztclog::pushFunction([](const ztclog::Line &line)
                         {
		// if (line.m_Type != ztclog::Line::Type::_line_debug_)
		{
			std::cout << line.m_Text << std::endl;
		} });

    using _App = SimpleApp;
    using _Desc = fxcc::platform::common::App::Desc;

    _Desc desc;
    desc.m_Pos = glm::ivec2(100, 100);
    desc.m_Size = glm::ivec2(900, 600);
    desc.m_ScaleFactor = 1.0f;

    desc.m_Title = "test mono";
    std::shared_ptr<_App> _app = std::make_shared<_App>(desc);
    return _app->Run();
};
